package com.pronosticnews.client.admin.view.listSaison;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.cell.client.ClickableTextCell;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.AsyncHandler;
import com.google.gwt.user.cellview.client.ColumnSortList;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.CellPreviewEvent;
import com.google.gwt.view.client.CellPreviewEvent.Handler;
import com.google.gwt.view.client.HasData;
import com.pronosticnews.client.admin.resources.PronosticnewsAdminMessages;
import com.pronosticnews.client.admin.resources.PronosticnewsAdminResources;
import com.pronosticnews.shared.model.ClassementDto;
import com.pronosticnews.shared.model.SaisonDto;

import fr.ysa.services.config.FiltreDto;
import fr.ysa.services.config.FiltreDto.TYPE;
import fr.ysa.services.config.ValueFiltreDto;
import fr.ysa.services.config.ValueFiltreDto.OPERATION;

public class ListSaisonViewImpl extends Composite implements ListSaisonView {

	interface ListSaisonUiBinder extends UiBinder<Widget, ListSaisonViewImpl> {
	}

	private class NameColumn extends Column<SaisonDto, String> {
		public NameColumn() {
			super(new ClickableTextCell());
		}

		@Override
		public String getValue(SaisonDto saison) {
			return saison.getNom();
		}

	}

	@UiField
	FlexTable classementHeader;

	@UiField
	FlexTable classementList;

	@UiField
	Label lblChargementClassement;

	@UiField
	VerticalPanel panelClassementSaison;

	@UiField
	SimplePager pager;

	@UiField
	DialogBox classementBox;

	@UiField
	DataGrid<SaisonDto> table;

	@UiField
	ListBox lstItemsPage;

	@UiField
	ListBox lstFiltreNom;

	@UiField
	TextBox txtFiltreNom;

	@UiField
	DialogBox suppressionBox;

	@UiField
	DisclosurePanel panel_list_filter;

	@UiField(provided = true)
	PronosticnewsAdminResources res;

	@UiField
	DockLayoutPanel dock;

	interface ClosurePanelFiltreStyle extends CssResource {
		String filtre_panel_close();

		String filtre_panel_open();
	}

	@UiField
	VerticalPanel panel_list_header;

	private Presenter presenter;

	private PronosticnewsAdminMessages messages;

	public ListSaisonViewImpl() {
		messages = GWT.create(PronosticnewsAdminMessages.class);
		res = GWT.create(PronosticnewsAdminResources.class);
		res.cssDeleteBoxElemTable().ensureInjected();
		res.cssListSaison().ensureInjected();
		initWidget(GWT.<ListSaisonUiBinder> create(ListSaisonUiBinder.class)
				.createAndBindUi(this));
		initFiltresName();
		createNameColumn();

		table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		AsyncHandler columnSortHandler = new AsyncHandler(table);
		table.addColumnSortHandler(columnSortHandler);

		table.addCellPreviewHandler(new Handler<SaisonDto>() {

			@Override
			public void onCellPreview(CellPreviewEvent<SaisonDto> event) {

				if (Event.getTypeInt(event.getNativeEvent().getType()) == Event.ONMOUSEOVER) {
					classementBox.hide();
				}
								
				if (Event.getTypeInt(event.getNativeEvent().getType()) == Event.ONCLICK
						&& event.getNativeEvent().getButton() == Event.BUTTON_LEFT) {
					displayClassement(event.getValue(), event.getNativeEvent().getClientX(), event.getNativeEvent().getClientY());
				}
				
				if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
					presenter.displayJournees();
				}
				
				if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_DELETE) {
					suppressionBox.center();
				}
			}
		});

		panel_list_filter.addOpenHandler(new OpenHandler<DisclosurePanel>() {
			@Override
			public void onOpen(OpenEvent<DisclosurePanel> event) {
				panel_list_filter.setStyleName(res.cssList()
						.filtre_panel_open());
				dock.setWidgetSize(panel_list_header,
						panel_list_filter.getOffsetHeight() + 40);
				dock.forceLayout();
			}
		});

		panel_list_filter.addCloseHandler(new CloseHandler<DisclosurePanel>() {
			@Override
			public void onClose(CloseEvent<DisclosurePanel> event) {
				panel_list_filter.setStyleName(res.cssList()
						.filtre_panel_close());
				dock.setWidgetSize(panel_list_header, 70);
				dock.forceLayout();
			}
		});

		initClassementTable();

	}
	
	SaisonDto saisonClassement;

	protected void displayClassement(SaisonDto saison, int left, int top) {
		if (saisonClassement == null || !saison.equals(saisonClassement)) {
			saisonClassement = saison;
			presenter.getClassement(saison);
			lblChargementClassement.setVisible(true);
			panelClassementSaison.setVisible(false);
		}		
		classementBox.center();
		classementBox.setPopupPosition(left, top);
	}

	private void initClassementTable() {
		classementHeader.getColumnFormatter().setWidth(0, "50px");
		classementHeader.getColumnFormatter().setWidth(1, "18px");
		classementHeader.getColumnFormatter().setWidth(2, "150px");
		classementHeader.getColumnFormatter().setWidth(3, "30px");
		classementHeader.getColumnFormatter().setWidth(4, "30px");
		classementHeader.getColumnFormatter().setWidth(5, "30px");
		classementHeader.getColumnFormatter().setWidth(6, "30px");
		classementHeader.getColumnFormatter().setWidth(7, "30px");
		classementHeader.getColumnFormatter().setWidth(8, "30px");
		classementHeader.getColumnFormatter().setWidth(9, "30px");
		classementHeader.getColumnFormatter().setWidth(10, "30px");

		classementList.getColumnFormatter().setWidth(0, "50px");
		classementList.getColumnFormatter().setWidth(1, "18px");
		classementList.getColumnFormatter().setWidth(2, "150px");
		classementList.getColumnFormatter().setWidth(3, "30px");
		classementList.getColumnFormatter().setWidth(4, "30px");
		classementList.getColumnFormatter().setWidth(5, "30px");
		classementList.getColumnFormatter().setWidth(6, "30px");
		classementList.getColumnFormatter().setWidth(7, "30px");
		classementList.getColumnFormatter().setWidth(8, "30px");
		classementList.getColumnFormatter().setWidth(9, "30px");
		classementList.getColumnFormatter().setWidth(10, "30px");

		classementHeader.getCellFormatter().setHorizontalAlignment(0, 1,
				HasHorizontalAlignment.ALIGN_LEFT);
		classementList.getCellFormatter().setHorizontalAlignment(0, 1,
				HasHorizontalAlignment.ALIGN_LEFT);

		classementHeader.setText(0, 0, messages.rang());
		classementHeader.setText(0, 1, "");
		classementHeader.setText(0, 2, messages.equipe());
		classementHeader.setText(0, 3, messages.abrPoints());
		classementHeader.setText(0, 4, messages.abrJoues());
		classementHeader.setText(0, 5, messages.abrGagnes());
		classementHeader.setText(0, 6, messages.abrNul());
		classementHeader.setText(0, 7, messages.abrPerdus());
		classementHeader.setText(0, 8, messages.abrButsPour());
		classementHeader.setText(0, 9, messages.abrButsContre());
		classementHeader.setText(0, 10, messages.abrDifferenceButs());
	}

	private void initFiltresName() {
		lstFiltreNom.addItem("égale", ValueFiltreDto.OPERATION.EQUAL.name());
		lstFiltreNom.addItem("contient", ValueFiltreDto.OPERATION.LIKE.name());
	}

	@UiHandler({ "txtFiltreNom" })
	void onFilterKeyPress(KeyPressEvent event) {
		if (event.getCharCode() == KeyCodes.KEY_ENTER) {
			sendFiltres();
		}
	}

	@UiHandler({ "lstFiltreNom" })
	void onLstFilterChange(ChangeEvent event) {
		sendFiltres();
	}

	@UiHandler("bt_clear_filtrer")
	void onClickClearFiltre(ClickEvent event) {
		txtFiltreNom.setText("");
		presenter.updateFiltreRequete(null);
	}

	private void sendFiltres() {
		List<FiltreDto> filtres = new ArrayList<FiltreDto>();
		filtres.add(getFiltreNom());
		presenter.updateFiltreRequete(filtres);
	}

	private FiltreDto getFiltreNom() {
		int operationIndex = lstFiltreNom.getSelectedIndex();
		String operation = lstFiltreNom.getValue(operationIndex);
		FiltreDto filtre = new FiltreDto();
		filtre.setName(SaisonDto.VALUE_NAME.nom.name());
		filtre.setType(TYPE.STRING);
		ValueFiltreDto valueFiltreDto = new ValueFiltreDto();
		valueFiltreDto.setValue(txtFiltreNom.getText());
		valueFiltreDto.setOperation(OPERATION.valueOf(operation));
		filtre.addValue(valueFiltreDto);
		return filtre;
	}

	private void createNameColumn() {
		Column<SaisonDto, String> nameColumn = new NameColumn();
		nameColumn.setDataStoreName(SaisonDto.VALUE_NAME.nom.name());
		nameColumn.setSortable(true);

		table.addColumn(nameColumn, messages.saison());
		table.getColumnSortList().push(nameColumn);
	}

	@Override
	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}

	@Override
	public HasData<SaisonDto> getHasData() {
		return table;

	}

	@Override
	public ColumnSortList getColumnSortList() {
		return table.getColumnSortList();
	}

	@UiHandler("btValiderSuppression")
	void onClickValiderSuppression(ClickEvent event) {
		suppressionBox.hide();
		presenter.supprimeSelected();
	}

	@UiHandler("btAnnulerSuppression")
	void onClickAnnulerSuppression(ClickEvent event) {
		suppressionBox.hide();
	}

	@UiHandler("lstItemsPage")
	void itemsPageValueChange(ChangeEvent event) {
		if (event.getSource().equals(lstItemsPage)) {
			int selectedIndex = lstItemsPage.getSelectedIndex();
			int nbItemsPage = Integer.parseInt(lstItemsPage
					.getValue(selectedIndex));
			table.setPageSize(nbItemsPage);
		}
	}

	@Override
	public void setSaison(int debut, List<SaisonDto> result) {
		table.setRowData(debut, result);
	}

	@Override
	public void setRowCount(Integer result) {
		table.setRowCount(result, true);
	}

	@Override
	public void setClassement(List<ClassementDto> result) {
		classementList.removeAllRows();
		int row = 0;
		for (ClassementDto classement : result) {
			classementList.setText(row, 0, classement.getPlace().toString());
			classementList.setWidget(
					row,
					1,
					new Image(com.google.gwt.core.client.GWT
							.getHostPageBaseURL()
							+ "image/?id="
							+ classement.getLogo() + "&width=15"));
			classementList.setText(row, 2, classement.getClub());
			classementList.setText(row, 3, classement.getPoints().toString());
			classementList.setText(row, 4, classement.getMatchsJoues()
					.toString());
			classementList.setText(row, 5, classement.getMatchsGagnes()
					.toString());
			classementList.setText(row, 6, classement.getMatchsNuls()
					.toString());
			classementList.setText(row, 7, classement.getMatchsPerdus()
					.toString());
			classementList.setText(row, 8, classement.getButsMarques()
					.toString());
			classementList.setText(row, 9, classement.getButsEncaisses()
					.toString());
			classementList.setText(row, 10, classement.getDifferenceButs()
					.toString());
			classementList.getCellFormatter().setStyleName(row, 1,
					res.cssListSaison().club_classement());
			if ((row % 2) == 0) {
				classementList.getRowFormatter().setStyleName(row,
						res.cssListSaison().row_altern());
			}
			row++;
		}
		lblChargementClassement.setVisible(false);
		panelClassementSaison.setVisible(true);

	}

	@Override
	public void stopDisplay() {
		classementBox.hide();
	}

}
